from datetime import datetime, timedelta
from django.db import transaction
from django.forms import model_to_dict
from Model.models import IncomeTotal, IncomeDetail, Equipment, Contract, Refund
from radius.models import Radcheck, Radusergroup, Radpostauth, Radacct
from .DateTools import timeCycle, getEndDateByDurationAndPackage


@transaction.atomic
def createIncomeTotal(contractId: int, clientId: int, incomeType: int, operator: str, memo=None):
    """
    :param contractId 合同编号
    :param clientId 客户编号
    :param incomeType 收入类型 1 新开 2 续费
    :param operator 操作人
    :param memo 备注
    """
    TotalData = IncomeTotal.objects.create(contract_id=contractId, client_id=clientId, income_type=incomeType,
                                           pay_time=datetime.now(), refund_state=0, operator=operator)
    TotalData.total_id = TotalData.id
    if memo is not None:
        TotalData.memo = memo
    TotalData.save()
    return TotalData.total_id


@transaction.atomic
def createIncomeDetail(totalId: int, contractId: int, detailType: int, amount: float, equipmentType=None,
                       code=None, memo=None):
    """
    :param totalId 收入编号
    :param contractId 合同编号
    :param detailType 收入类型 1，套餐费2，初装费，3，迁移 4，增值业务
    :param amount 收入金额
    :param equipmentType 设备类型
    :param code 设备编码
    :param memo 备注
    """
    datailData = IncomeDetail.objects.create()
    datailData.detail_id = datailData.id
    datailData.total_id = totalId
    datailData.contract_id = contractId
    datailData.detail_type = detailType
    datailData.pay_time = datetime.now()
    datailData.refund_state = 0
    datailData.amount = amount
    if equipmentType is not None:
        datailData.equipment_type = equipmentType
    if code is not None:
        datailData.equipment_code = code
    if memo is not None:
        datailData.memo = memo
    datailData.save()
    return True


@transaction.atomic
def createAuthInfo(username: str, password: str, packageId: int, endDate: str):
    """
    :param username 账号
    :param password 密码
    :param packageId 套餐ID
    :param endDate 到期时间 格式 2022-05-22
    """
    Radcheck.objects.filter(username=username).delete()
    Radusergroup.objects.filter(username=username).delete()
    Radcheck.objects.create(username=username, attribute='Cleartext-Password', op=':=', value=password)
    Radcheck.objects.create(username=username, attribute='expiration', op=':=', value=timeCycle(endDate))
    Radusergroup.objects.create(username=username, groupname=packageId, priority=1)
    return True


@transaction.atomic
def updateEquipment(state: int, code: str, username: str):
    """
    :param state 设备使用状态  0 闲置 1 启用 2 更换
    :param code 设备码
    :param username 被使用人
    """
    try:
        updateData = Equipment.objects.get(equipment_code=code.strip())
        updateData.use_status = state
        updateData.access_number = username
        updateData.start_date = datetime.now()
        updateData.save()
    except:
        pass


def getOnlineState(username):
    """
    :param username 宽带账号
    """
    # 查询拨号请求
    currentDay = datetime.now().date()
    if Contract.objects.filter(account_number=username).last().end_date.date() > currentDay:
        state = "正常"
        info = str(currentDay)
    else:
        state = "停用"
        info = "当前已停用"
    # info = ""
    # if not Radpostauth.objects.filter(username=username).exists():
    #     if Contract.objects.filter(account_number=username).last().end_date.date() > currentDay:
    #         state = "正常"
    #     else:
    #         state = "停用"
    # else:
    # radstatus = Radpostauth.objects.filter(username=username).last()
    # accept = '拨号请求通过'
    # state = accept if radstatus.reply == 'Access-Accept' else '拨号请求失败,用户端输入密码为{}'.format(radstatus.pass_field)
    # if state != '未查询到拨号请求':
    #     # 查询在线情况
    #     acceptuser = Radacct.objects.filter(username=username).last()
    #     mac = acceptuser.callingstationid
    #     mac = mac[0:2] + mac[3:5] + '-' + mac[6:8] + mac[9:11] + '-' + mac[12:14] + mac[15:]
    #     vlanId = acceptuser.nasportid[12:21] if 'trunk' in acceptuser.nasportid else acceptuser.nasportid
    #     if acceptuser.acctstoptime is None or acceptuser.acctstoptime == "":
    #         # 上线时间
    #         state = '当前在线'
    #         onlinetime = acceptuser.acctstarttime.strftime('%Y-%m-%d %H:%M:%S')
    #     else:
    #         state = '当前离线'
    #         # 离线时间
    #         onlinetime = acceptuser.acctstoptime.strftime('%Y-%m-%d %H:%M:%S')
    #     info = f'时间为{onlinetime} MAC地址为：{mac} VLAN为：{vlanId}'
    # else:
    #     info = '暂无时间'
    return state, info


@transaction.atomic
def createRenewContract(oldData: Contract, packageId: int, operator: str, memo=None):
    """
    :param oldData 被续费数据
    :param packageId 续费套餐
    :param operator 当前操作人
    :param memo 备注
    """
    renewData = Contract.objects.create()
    renewData.contract_id = renewData.id
    renewData.client_id = oldData.client_id
    renewData.linkman = oldData.linkman
    renewData.link_telephone = oldData.link_telephone
    renewData.service_package = packageId
    renewData.start_date = oldData.end_date
    renewData.end_date = getEndDateByDurationAndPackage(packageId, str(oldData.end_date)[:10])
    oldData.state = 2
    oldData.renew_state = 1
    renewData.state = 1
    renewData.renew_state = 0
    renewData.district = oldData.district
    renewData.subdistrict = oldData.subdistrict
    renewData.community = oldData.community
    renewData.address = oldData.address
    renewData.detail_address = oldData.detail_address
    renewData.install_address = oldData.install_address
    renewData.create_date = datetime.now()
    renewData.account_number = oldData.account_number
    renewData.account_password = oldData.account_password
    renewData.operator = operator
    if memo is not None:
        renewData.memo = memo
    renewData.save()
    return renewData


@transaction.atomic
def deleteAuth(username: str):
    """
    :param username 被删除用户
    """
    Radacct.objects.filter(username=username).delete()
    Radusergroup.objects.filter(username=username).delete()
    return True


@transaction.atomic
def createRefund(operator: str, detailId: int, data: dict, all_state=None):
    """
    :param  operator 操作人
    :param detailId 收入详细ID
    :param data request.body
    :param all_state 是否全部退费
    """
    try:
        Product = {0: '网时费用', 1: '光猫费用', 2: '路由器费', None: None}
        createData = Refund.objects.create()
        createData.redund_id = createData.id
        createData.contract_id = data.get('contractId', None)
        createData.detail_id = detailId
        createData.refund_type = data.get('refund_type', None)
        createData.bank_number = data.get('bank_number', None)
        createData.bank_name = data.get('bank_name', None)
        createData.bank = data.get('bank', None)
        if not all_state:
            createData.refund_product = Product[int(data.get('expense_type', None))]
        else:
            createData.refund_product = '全部退费'
        createData.money = float(data.get('expense_total'))
        createData.memo = data.get('memo', None)
        createData.refund_date = datetime.now()
        createData.operator = operator
        createData.save()
    except:
        pass


@transaction.atomic
def updataIncome(contractId: int):
    """
    更新合同收入 仅限退费使用
    :param contractId 合同编号
    """
    IncomeTotal.objects.filter(contract_id=contractId).update(amount=0, refund_state=0, refund_time=datetime.now())
    IncomeDetail.objects.filter(contract_id=contractId).update(amount=0, refund_state=0, refund_time=datetime.now())
    return True
